package org.eenie.core.view.bar

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.util.AttributeSet
import android.util.TypedValue
import android.view.*
import android.widget.FrameLayout
import androidx.annotation.MenuRes
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.ActionMenuView
import androidx.core.internal.view.SupportMenuItem.SHOW_AS_ACTION_ALWAYS
import androidx.core.view.children
import dev.chrisbanes.insetter.Insetter
import dev.chrisbanes.insetter.applyInsetter
import dev.chrisbanes.insetter.windowInsetTypesOf
import org.eenie.core.R
import org.eenie.core.databinding.SubAppbarLayoutBinding
import org.eenie.core.ext.onClick

/**
 * V1.0.0
 */

class AppBar(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs), ActionMenuView.OnMenuItemClickListener {

    private val mBinding: SubAppbarLayoutBinding = SubAppbarLayoutBinding.inflate(LayoutInflater.from(context), this, true)
    private var mTitle: CharSequence = ""
    private var mSubTitle: CharSequence = ""
    private var menuTextColor = Color.WHITE
    private var menuTextSize: Float = 0f
    private var defaultHeight = 45f
    private lateinit var mIcon: Drawable
    private var showIcon = true
    private var mNavMenuClickListener: NavMenuClickListener? = null


    init {


        attrs?.let {
            initAttrs(it)
        }

    }


    @SuppressLint("UseCompatLoadingForDrawables")
    private fun initAttrs(attrs: AttributeSet) {

        val array = context.obtainStyledAttributes(attrs, R.styleable.AppBar, 0, 0)

        val icon = array.getDrawable(R.styleable.AppBar_app_bar_nav_icon) ?: resources.getDrawable(R.mipmap.ic_back_light, context.theme)
        val title = array.getString(R.styleable.AppBar_app_bar_title) ?: ""
        val titleColor = array.getColor(R.styleable.AppBar_app_bar_title_color, Color.WHITE)
        val titleSize = array.getDimension(R.styleable.AppBar_app_bar_title_size, sp2px(14f))


        val subtitle = array.getString(R.styleable.AppBar_app_bar_subtitle) ?: ""
        val subtitleColor = array.getColor(R.styleable.AppBar_app_bar_subtitle_color, Color.WHITE)
        val subtitleSize = array.getDimension(R.styleable.AppBar_app_bar_subtitle_size, sp2px(10f))
        val iconPadding = array.getDimension(R.styleable.AppBar_app_bar_content_padding_left, sp2px(10f))


        val menuId = array.getResourceId(R.styleable.AppBar_app_bar_nav_menu, -1)
        menuTextColor = array.getColor(R.styleable.AppBar_app_bar_menu_text_color, Color.WHITE)
        menuTextSize = array.getDimension(R.styleable.AppBar_app_bar_menu_text_size, sp2px(12f))


        val fit = array.getBoolean(R.styleable.AppBar_app_bar_fits_system_windows, true)

        if (fit) {
            mBinding.root.applyInsetter {
                type(statusBars = true, displayCutout = true) {
                    margin(top = true)

                }
            }
        }


        val height = array.getDimension(R.styleable.AppBar_app_bar_content_height, -1f)
        setContentHeight(height.toInt())

        val gravity = array.getInteger(R.styleable.AppBar_app_bar_title_gravity, Gravity.CENTER)
        setContentGravity(gravity)

        setIcon(icon)

        setNavPaddingLeft(iconPadding.toInt())

        setTitle(title)
        setTitleColor(titleColor)
        setTitleSize(titleSize)

        setSubtitle(subtitle)
        setSubtitleColor(subtitleColor)
        setSubtitleSize(subtitleSize)


        inflateMenu(menuId)


//        mBinding.layAction.menu.add("测试").apply {
//            this.setShowAsAction(SHOW_AS_ACTION_ALWAYS)
//        }


        val showIcon = array.getBoolean(R.styleable.AppBar_app_bar_nav_visibility, true)
        setIconGone(showIcon)
        array.recycle()

    }


    fun setContentHeight(height: Int) {
        if (height > 0) {
            val lp = mBinding.root.layoutParams
            lp.height = height
            mBinding.root.layoutParams = lp
        }
    }


    override fun onFinishInflate() {
        super.onFinishInflate()


        bindNavAction()

        mBinding.layAction.setOnMenuItemClickListener(this)


    }


    private fun bindNavAction() {
        mBinding.layNav.onClick {
            (context as? Activity)?.onBackPressed()
        }
    }


    fun setIcon(icon: Drawable) {
        mIcon = icon
        mBinding.btnNav.setImageDrawable(icon)
    }


    fun setNavPaddingLeft(left: Int) {
        mBinding.layNav.setPadding(left, 0, 0, 0)
    }

    fun setContentGravity(gravity: Int) {
        mBinding.layContent.gravity = gravity
        val lp = (mBinding.layContent.layoutParams as LayoutParams)

        if (gravity == Gravity.LEFT) {
            lp.gravity = Gravity.CENTER_VERTICAL or Gravity.LEFT
            lp.marginStart = sp2px(defaultHeight).toInt()
        } else {
            lp.gravity = gravity
        }

        mBinding.layContent.layoutParams = lp
    }

    fun setIconGone(gone: Boolean) {
        showIcon = gone
        mBinding.layNav.visibility = if (showIcon) View.VISIBLE else View.GONE
    }

    fun setTitle(title: CharSequence) {
        mTitle = title
        if (TextUtils.isEmpty(mTitle)) {
            mBinding.tvTitle.text = ""
            mBinding.tvTitle.visibility = View.GONE
        } else {
            mBinding.tvTitle.text = mTitle
            mBinding.tvTitle.visibility = View.VISIBLE
        }
    }


    fun setTitleColor(color: Int) {
        mBinding.tvTitle.setTextColor(color)

    }

    fun setTitleSize(sizePx: Float) {
        mBinding.tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, sizePx)
    }

    fun setSubtitle(subtitle: CharSequence) {
        mSubTitle = subtitle
        if (TextUtils.isEmpty(mSubTitle)) {
            mBinding.tvSubtitle.text = ""
            mBinding.tvSubtitle.visibility = View.GONE
        } else {
            mBinding.tvSubtitle.text = mSubTitle
            mBinding.tvSubtitle.visibility = View.VISIBLE
        }
    }

    fun setSubtitleColor(color: Int) {
        mBinding.tvSubtitle.setTextColor(color)

    }

    fun setSubtitleSize(sizePx: Float) {
        mBinding.tvSubtitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, sizePx)
    }

    @SuppressLint("RestrictedApi", "ResourceType")
    private fun inflateMenu(@MenuRes resId: Int) {
        if (resId > 0) {
            val menu = getMenu()
            menu.setDefaultShowAsAction(SHOW_AS_ACTION_ALWAYS)
            getMenuInflater().inflate(resId, menu)
            getMenuItemViews().forEach {
                it.setTextColor(menuTextColor)
                it.setTextSize(TypedValue.COMPLEX_UNIT_PX, menuTextSize)
            }
        }
    }

    private fun getMenuInflater(): MenuInflater {
        return MenuInflater(context)
    }

    fun getMenu(): MenuBuilder {

        return mBinding.layAction.menu as MenuBuilder
    }

    fun getMenuItemViews(): List<ActionMenuItemView> {
        return mBinding.layAction.children.toMutableList().map {
            it as ActionMenuItemView
        }
    }


    fun getViewBinding(): SubAppbarLayoutBinding {
        return mBinding
    }


    fun setNavClickListener(listener: View.OnClickListener) {
        mBinding.layNav.setOnClickListener(listener)
    }

    fun setContentClickListener(listener: View.OnClickListener) {
        mBinding.layContent.setOnClickListener(listener)
    }

    fun setMenuClickListener(listener: NavMenuClickListener) {
        mNavMenuClickListener = listener
    }

    @SuppressLint("RestrictedApi")
    fun addMenuItem(text: CharSequence, icon: Int = 0): ActionMenuItemView {
        getMenu().add(text)
        val itemView = mBinding.layAction.children.last() as ActionMenuItemView
        itemView.setTextColor(menuTextColor)
        itemView.setTextSize(TypedValue.COMPLEX_UNIT_PX, menuTextSize)
        return itemView
    }

    private fun sp2px(dp: Float): Float {
        val fontScale = resources.displayMetrics.scaledDensity
        return (dp * fontScale + 0.5f)
    }

    @SuppressLint("RestrictedApi")
    override fun onMenuItemClick(item: MenuItem): Boolean {
        val index = getMenu().actionItems.indexOf(item)
        val view = getMenuItemViews()[index]
        mNavMenuClickListener?.onMenuClick(item, view)
        return true
    }


}